package cn.zs.supply.common.core.security.simple;
import cn.zs.supply.common.constants.enums.PubErrCode;
import cn.zs.supply.common.utils.ResponseUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.jwt.crypto.sign.RsaSigner;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class ApplicationConfigurerAdapter extends WebSecurityConfigurerAdapter {

    @Autowired
    private RsaVerifier verifier;

    @Autowired
    private RsaSigner signer;

    @Autowired
    private JwtUserDetailServiceImpl jwtUserDetailService;

    @Autowired
    private LoginSuccessHandler loginSuccessHandler;


    @Autowired
    private JwtHeadFilter headFilter;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //登录过滤器
        JwtLoginFilter jwtLoginFilter=new JwtLoginFilter();
        jwtLoginFilter.setAuthenticationManager(this.authenticationManagerBean());
        //登录成功和失败的操作
        //LoginSuccessHandler loginSuccessHandler = new LoginSuccessHandler();
        loginSuccessHandler.setSigner(signer);
        jwtLoginFilter.setAuthenticationSuccessHandler(loginSuccessHandler);
        jwtLoginFilter.setAuthenticationFailureHandler(new LoginFailureHandler());

        //登录过滤器
        JwtAuthenticationProvider provider = new JwtAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder());
        provider.setUserDetailsService(jwtUserDetailService);

        //JWT校验过滤器
        headFilter.setVerifier(verifier);
        //身份验证入口
        http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
            JSONObject responseJson=new JSONObject();
            responseJson.put("code", PubErrCode.NOT_LOGINED.getCode());
            responseJson.put("errcode",PubErrCode.NOT_LOGINED.getCode());
            responseJson.put("msg",PubErrCode.NOT_LOGINED.getMsg());
            responseJson.put("success", "true");
            ResponseUtil.setResponse(response,responseJson); })
                //拒绝访问处理,当已登录,但权限不足时调用
            .accessDeniedHandler((request, response, accessDeniedException) -> {
                JSONObject responseJson=new JSONObject();
                responseJson.put("code", PubErrCode.NO_PERMISSION.getCode());
                responseJson.put("errcode",PubErrCode.NO_PERMISSION.getCode());
                responseJson.put("msg",PubErrCode.NO_PERMISSION.getMsg());
                responseJson.put("success", "true");
                ResponseUtil.setResponse(response,responseJson); })
                .and()
                .authorizeRequests()
                .anyRequest().access("@accessDecisionService.hasPermission(request , authentication)")
                .and()
                //将授权提供者注册到授权管理器中(AuthenticationManager)
                .authenticationProvider(provider)
                .addFilterAfter(jwtLoginFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilterAfter(headFilter, JwtLoginFilter.class)
                //禁用session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
